#include "ResLoader.h"
#include <stdio.h>
#include <stdlib.h>
#include "../Detour/DetourNavMesh.h"
#include "./TempObstaclesNavMesh.h"
static const int NAVMESHSET_MAGIC = 'M' << 24 | 'S' << 16 | 'E' << 8 | 'T'; //'MSET';
static const int NAVMESHSET_VERSION = 1;
struct NavMeshSetHeader
{
	int magic;
	int version;
	int numTiles;
	dtNavMeshParams params;
};

struct NavMeshTileHeader
{
	dtTileRef tileRef;
	int dataSize;
};

dtNavMesh* ResLoader::LoadNaviMesh(const std::string path)
{
	FILE* fp = fopen(path.c_str(), "rb");
	if (!fp) return NULL;

	// Read header.
	NavMeshSetHeader header;
	size_t readLen = fread(&header, sizeof(NavMeshSetHeader), 1, fp);
	if (readLen != 1)
	{
		fclose(fp);
		return NULL;
	}
	if (header.magic != NAVMESHSET_MAGIC)
	{
		fclose(fp);
		return NULL;
	}
	if (header.version != NAVMESHSET_VERSION)
	{
		fclose(fp);
		return NULL;
	}

	dtNavMesh* mesh = dtAllocNavMesh();
	if (!mesh)
	{
		fclose(fp);
		return NULL;
	}
	dtStatus status = mesh->init(&header.params);
	if (dtStatusFailed(status))
	{
		fclose(fp);
		return NULL;
	}

	// Read tiles.
	for (int i = 0; i < header.numTiles; ++i)
	{
		NavMeshTileHeader tileHeader;
		readLen = fread(&tileHeader, sizeof(tileHeader), 1, fp);
		if (readLen != 1)
		{
			fclose(fp);
			return NULL;
		}

		if (!tileHeader.tileRef || !tileHeader.dataSize)
			break;

		unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);
		if (!data) break;
		memset(data, 0, tileHeader.dataSize);
		readLen = fread(data, tileHeader.dataSize, 1, fp);
		if (readLen != 1)
		{
			dtFree(data);
			fclose(fp);
			return NULL;
		}

		mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);
	}

	fclose(fp);

	return mesh;
}

TempObstaclesNavMesh* ResLoader::LoadTempObstaclesNavMesh(std::string path)
{
	TempObstaclesNavMesh* toNaveMesh = new TempObstaclesNavMesh();
	if (toNaveMesh->LoadNavMesh(path))
	{
		return toNaveMesh;

	}
	else {
		delete toNaveMesh;
		return NULL;
	}
}
